/*
 * Metric.h
 *
 *  Created on: May 25, 2011
 *      Author: marchi
 */

#ifndef LINKEDCELLS_SRC_METRIC_H_
#define LINKEDCELLS_SRC_METRIC_H_
#include <cmath>
#include "Ftypedefs.h"
#include "MyVec.h"
#include <vector>

using namespace std;

class Metric {
	matrix co, oc;
	static const matrix Idtity;
	void invertCO();
	int count;
	double AA(){return norm(co[XX]);}
	double BB(){return norm(co[YY]);}
	double CC(){return norm(co[ZZ]);}
	double Alpha(){
		double alpha;
		if (norm2(co[YY])*norm2(co[ZZ])!=0)
			alpha = acos(cos_angle(co[YY],co[ZZ]));
		else
			alpha = 0.5*M_PI;
		return alpha;
	}
	double Beta(){
		double beta;
		if (norm2(co[XX])*norm2(co[ZZ])!=0)
			beta  = acos(cos_angle(co[XX],co[ZZ]));
		else
			beta  = 0.5*M_PI;
		return beta;
	}

	double Gamma(){
		double gamma;
		if (norm2(co[XX])*norm2(co[YY])!=0)
			gamma = acos(cos_angle(co[XX],co[YY]));
		else
			gamma = 0.5*M_PI;
		return gamma;
	}
public:
	Metric();
	Metric(const matrix &);
	Metric(const Metric &);
	virtual ~Metric();
	Metric & operator()(const matrix &);
	Metric & operator()(const Metric &);
	Metric & operator=(const Metric & );
	Metric & operator+=(const Metric &);
	Metric operator/(const double);
	const matrix & getCO() const {return co;};
	const matrix & getOC() const {return oc;};

	double getVol(){ return (double) (co[XX][XX]*(co[YY][YY]*co[ZZ][ZZ]-co[ZZ][YY]*co[YY][ZZ])
		  -co[YY][XX]*(co[XX][YY]*co[ZZ][ZZ]-co[ZZ][YY]*co[XX][ZZ])
		  +co[ZZ][XX]*(co[XX][YY]*co[YY][ZZ]-co[YY][YY]*co[XX][ZZ]));};
	vector<double> getParas(){
		vector<double> d=vector<double>(DIM*2);
		d[0]=AA();
		d[1]=BB();
		d[2]=CC();
		d[3]=RAD2DEG*Alpha();
		d[4]=RAD2DEG*Beta();
		d[5]=RAD2DEG*Gamma();
		return d;}
};

#endif /* LINKEDCELLS_SRC_METRIC_H_ */
